package com.yjm.test.Spring5.ch4;

import java.io.File;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Lazy;
import org.springframework.context.support.GenericApplicationContext;
import org.springframework.context.support.GenericXmlApplicationContext;

//@Component
public class DestructiveBeanWithInterface implements BeanNameAware, ApplicationContextAware, InitializingBean, DisposableBean {
	private String name;
	private File file;
	private String filePath;
	@Override
	public void setBeanName(String name) {
		System.out.println(this.getClass().getCanonicalName() + "->setBeanName(" + name + ");");
		this.name = name;
	}
	@Override
	public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
		System.out.println(this.getClass().getCanonicalName() + "->setApplicationContext(" + applicationContext + ");");
	}
	
	
	public void initMethod() {
		System.out.println(this.getClass().getCanonicalName() + "->initMethod");
	}
	public void destroyMethod() {
		System.out.println(this.getClass().getCanonicalName() + "->destroyMethod");
	}
	
	
	@Override
	public void afterPropertiesSet() throws Exception {
		System.out.println(this.getClass().getCanonicalName() + "->afterPropertiesSet() InitializingBean");
		System.out.println("Initializing Bean filePath:" + filePath);
		if (filePath == null) {
			throw new IllegalArgumentException("You must specify the filePath property of " + this.getClass());
		}
		
		this.file = new File(filePath);
		file.createNewFile();
		System.out.println("file exists:" + file.exists());
	}
	@Override
	public void destroy() {
		System.out.println("destroying bean " + this.getClass());
		if (!file.delete()) {
			System.err.println("Error: delete file failed!");
		}
		System.out.println("File exists: " + file.exists());
	}
	
	@PostConstruct
	public void postConstruct() {
		System.out.println(this.getClass().getCanonicalName() + "->postConstruct() annotation");
	}
	
	@PreDestroy
	public void preDestroy() {
		System.out.println(this.getClass().getCanonicalName() + "->preDestroy() annotation");
	}
	
	public String getFilePath() {
		return filePath;
	}

	public void setFilePath(String filePath) {
		this.filePath = filePath;
	}

	public static void testXml() {
		GenericXmlApplicationContext ctx = new GenericXmlApplicationContext();
		ctx.load("classpath:spring/application-context-annotation.xml");
		ctx.refresh();
		DestructiveBeanWithInterface b = ctx.getBean(DestructiveBeanWithInterface.class);
		
		//ctx.close();
		ctx.registerShutdownHook();
	}
	
	@Configuration
	@ComponentScan(basePackages="com.yjm.test.Spring5.ch4")
	public static class AnnotationBeanConfig123 {
		@Lazy
		@Bean(initMethod="initMethod", destroyMethod="destroyMethod")
		DestructiveBeanWithInterface getDestructiveBean() {
			DestructiveBeanWithInterface a = new DestructiveBeanWithInterface();
			a.setFilePath("d:/test.txt");
			return a;
		}
	}
	
	public static void testAnnotation() {
		GenericApplicationContext ctx = new AnnotationConfigApplicationContext(AnnotationBeanConfig123.class);
		
		DestructiveBeanWithInterface a = ctx.getBean(DestructiveBeanWithInterface.class);
		
		//ctx.close();
		ctx.registerShutdownHook();
	}
	
	

	public static void main(String args[]) throws Exception {
		testXml();
		System.out.println("\n\n\n\n\n\n");
		testAnnotation();
	}



	
}
